#include "tim.h"

static GPIO_InitTypeDef  GPIO_InitStructure;
static NVIC_InitTypeDef   NVIC_InitStructure;
static TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
static TIM_OCInitTypeDef  TIM_OCInitStructure;
	
// 配置定时器1
void TIM1_Config(void)
{
	/* 1.打开定时器时钟 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
	
	/* 2.配置中断优先级 */
	NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	/* 3.定时器基础配置 */
	TIM_TimeBaseStructure.TIM_Period = (10000/10)-1;		// 计数周期
	TIM_TimeBaseStructure.TIM_Prescaler = 16800-1;	// 预分频系数(定时器计数频率：168MHz/16800=10kHz)
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;	// 时钟分割（STM32F407不支持）
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;		// 向上计数
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
	
	/* 4.使能定时器更新中断 */
	TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
	
	/* 5.打开定时器 */
	TIM_Cmd(TIM1, ENABLE);
}


// 配置定时器2
void TIM2_Config(void)
{
	/* 1.打开定时器时钟 */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	/* 2.配置中断优先级 */
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	/* 3.定时器基础配置 */
	TIM_TimeBaseStructure.TIM_Period = (10000/5)-1;		// 计数周期
	TIM_TimeBaseStructure.TIM_Prescaler = 8400-1;	// 预分频系数(定时器计数频率：84MHz/8400=10kHz)
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;	// 时钟分割（STM32F407不支持）
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;		// 向上计数
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
	
	/* 4.使能定时器更新中断 */
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	/* 5.打开定时器 */
	TIM_Cmd(TIM2, ENABLE);
}

// 配置定时器3
void TIM3_Config(void)
{
	/* 1.打开定时器时钟 */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	
	/* 2.配置中断优先级 */
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	/* 3.定时器基础配置 */
	TIM_TimeBaseStructure.TIM_Period = (10000/2)-1;		// 计数周期
	TIM_TimeBaseStructure.TIM_Prescaler = 8400-1;	// 预分频系数(定时器计数频率：84MHz/8400=10kHz)
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;	// 时钟分割（STM32F407不支持）
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;		// 向上计数
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
	
	/* 4.使能定时器更新中断 */
	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
	
	/* 5.打开定时器 */
	TIM_Cmd(TIM3, ENABLE);
}

// 配置定时器8
void TIM8_Config(void)
{
	/* 1.打开定时器时钟 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
	
	/* 2.配置中断优先级 */
	NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	/* 3.定时器基础配置 */
	TIM_TimeBaseStructure.TIM_Period = (10000*4)-1;		// 计数周期
	TIM_TimeBaseStructure.TIM_Prescaler = 16800-1;	// 预分频系数(定时器计数频率：168MHz/16800=10kHz)
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;	// 时钟分割（STM32F407不支持）
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;		// 向上计数
	TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
	
	/* 4.使能定时器更新中断 */
	TIM_ITConfig(TIM8, TIM_IT_Update, ENABLE);
	
	/* 5.打开定时器 */
	TIM_Cmd(TIM8, ENABLE);
}

// 配置定时器14通道1（输出PWM到PF9）
void TIM14_Config(void)
{
	/* 1.打开定时器时钟 */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE);
		/* GPIO时钟 */
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
	
	/* 2.GPIO配置 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;	// 复用功能模式(TIM14_CH1)
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
	GPIO_Init(GPIOF, &GPIO_InitStructure); 
	
	/* 3.连接复用功能引脚 */  
	GPIO_PinAFConfig(GPIOF, GPIO_PinSource9, GPIO_AF_TIM14);

	/* 4.定时器基础配置 */
	TIM_TimeBaseStructure.TIM_Period = (10000/100)-1;		// 周期
	TIM_TimeBaseStructure.TIM_Prescaler = 8400-1;	// 计数频率: 84MHz/8400=10kHz
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;	// 无效属性
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;	// 向上计数
	TIM_TimeBaseInit(TIM14, &TIM_TimeBaseStructure);
	
	/* 5.配置PWM */
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;			// PWM模式1
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	// 打开PWM
	TIM_OCInitStructure.TIM_Pulse = 90;						// 比较值（占空比：比较值/周期）
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;	// 初始极性（高电平）
		// 通道1配置
	TIM_OC1Init(TIM14, &TIM_OCInitStructure);
	TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable);
	
	// 6.定时器重装载配置
	TIM_ARRPreloadConfig(TIM14, ENABLE);
	
	/* 7.定时器使能 */
	TIM_Cmd(TIM14, ENABLE);
}

// 定时器1中断服务函数（触发条件：间隔100ms）
void TIM1_UP_TIM10_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
	{
		LED1 = ~LED1;
		
		TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
	}
}


// 定时器2中断服务函数（触发条件：间隔200ms）
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
	{
		LED2 = ~LED2;
		
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

// 中断服务函数（触发条件：间隔500ms）
void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
	{
		LED3 = ~LED3;
		
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
	}
}

// 中断服务函数（触发条件：间隔4000ms）
void TIM8_UP_TIM13_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM8, TIM_IT_Update) != RESET)
	{
		LED4 = ~LED4;
		
		TIM_ClearITPendingBit(TIM8, TIM_IT_Update);
	}
}
